package com.jzsk.variable.center.common.utils.redis;

import com.jzsk.variable.center.common.utils.prop.Prop;
import com.jzsk.variable.center.common.utils.prop.PropUtils;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * JedisPool连接池工厂类
 *
 * @author jiangli  2017/9/28
 * @version v1.0
 */
public class JedisPoolFactory {

    private static final JedisPoolFactory JEDIS_POOL_FACTORY = new JedisPoolFactory();

    private static final Map<String, JedisPool> POOL_LIST = new ConcurrentHashMap<>();

    private JedisPoolFactory() {
    }

    public static JedisPoolFactory getInstance() {
        return JEDIS_POOL_FACTORY;
    }

    /**
     * 新增一个池
     *
     * @param fileName 文件名，相对于类的根路径的路径
     */
    public void add(String fileName) {
        if (POOL_LIST.get(fileName) == null) {
            POOL_LIST.put(fileName, buildJedisPool(fileName));
        }
    }

    private JedisPool buildJedisPool(String fileName) {
        Prop prop = PropUtils.use(fileName);
        String host = prop.get("redis.host");
        int port = prop.getInt("redis.port", 6379);
        String password = prop.get("redis.password");
        if (password != null && "".equals(password.trim())) {
            password = null;
        }
        int timeOut = prop.getInt("redis.timeout", 5000);
        int database = prop.getInt("redis.database", 0);

        int maxTotal = prop.getInt("redis.maxTotal", 10000);
        int maxIdle = prop.getInt("redis.maxIdle", 2000);
        int maxWaitMillis = prop.getInt("redis.maxWaitMillis", 5000);
        boolean testOnBorrow = prop.getBoolean("redis.testOnBorrow", false);

        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(maxTotal);
        config.setMaxIdle(maxIdle);
        config.setMaxWaitMillis(maxWaitMillis);
        config.setTestOnBorrow(testOnBorrow);
        return new JedisPool(config, host, port, timeOut, password, database);
    }

    public JedisPool getJedisPool(String fileName) {
        JedisPool jedisPool = POOL_LIST.get(fileName);
        if (jedisPool == null) {
            add(fileName);
            return POOL_LIST.get(fileName);
        }
        return jedisPool;
    }

    public void add(JedisConfig jedisConfig) {
        if (POOL_LIST.get(jedisConfig.key()) == null) {
            POOL_LIST.put(jedisConfig.key(), buildJedisPool(jedisConfig));
        }
    }

    private JedisPool buildJedisPool(JedisConfig jedisConfig) {
        String password = jedisConfig.getPassword();
        if (password != null && "".equals(password.trim())) {
            password = null;
        }
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(jedisConfig.getMaxTotal());
        config.setMaxIdle(jedisConfig.getMaxIdle());
        config.setMaxWaitMillis(jedisConfig.getMaxWaitMillis());
        config.setTestOnBorrow(jedisConfig.isTestOnBorrow());
        return new JedisPool(config, jedisConfig.getHost(), jedisConfig.getPort(), jedisConfig.getTimeout(),
                password, jedisConfig.getDatabase());
    }

    public JedisPool getJedisPool(JedisConfig jedisConfig) {
        JedisPool jedisPool = POOL_LIST.get(jedisConfig.key());
        if (jedisPool == null) {
            add(jedisConfig);
            return POOL_LIST.get(jedisConfig.key());
        }
        return jedisPool;
    }

}
